

#ifndef __BLE_STACK_ARCH_H__
#define __BLE_STACK_ARCH_H__


#include "rwip_config.h"       // SW configuration
#include <stdint.h>            // standard integer definition                                   
#include "ln_compiler.h"       // standard integer definition                                   
                                   
                                   
                                   
/// ARM is a 32-bit CPU
#define CPU_WORD_SIZE   4

/// ARM is little endian
#define CPU_LE          1

/*
 * DEBUG configuration
 ****************************************************************************************
 */
#if defined(CFG_DBG)
  #define PLF_DEBUG          1
#else //CFG_DBG
  #define PLF_DEBUG          0
#endif //CFG_DBG

////NVDS
#ifdef CFG_NVDS
  #define PLF_NVDS           1
#else
  #define PLF_NVDS           0
#endif//CFG_NVDS

typedef struct 
{
    uint16_t  id;
    uint16_t  len;
    void     *msg;
} rw_queue_msg_t;

void rw_queue_msg_send(uint8_t event_type, uint16_t len, void *msg);
void platform_reset(uint32_t error);
void app_init(void);
void rw_init(void);


/// Possible errors detected by FW
#define RESET_NO_ERROR          (0x00000000)/// Reset platform (ok)
#define RESET_MEM_ALLOC_FAIL    (0xF2F2F2F2)/// Reset platform (mem alloc filed)
#define RESET_TO_ROM            (0xA5A5A5A5)/// Reset platform and stay in ROM
#define RESET_AND_LOAD_FW       (0xC3C3C3C3)/// Reset platform and reload FW

/// Exchange memory size limit
#if (BT_DUAL_MODE)
  #define    EM_SIZE_LIMIT          0x10000
#else
  #define    EM_SIZE_LIMIT          0x8000
#endif 

#if PLF_DEBUG
  /**
   ****************************************************************************************
   * @brief Print the assertion error reason and loop forever.
   *
   * @param condition C string containing the condition.
   * @param file C string containing file where the assertion is located.
   * @param line Line number in the file where the assertion is located.
   ****************************************************************************************
   */
  void assert_err(const char *condition, const char * file, int line);
  
  /**
   ****************************************************************************************
   * @brief Print the assertion error reason and loop forever.
   * The parameter value that is causing the assertion will also be disclosed.
   *
   * @param param0 parameter value 0.
   * @param param1 parameter value 1.
   * @param file C string containing file where the assertion is located.
   * @param line Line number in the file where the assertion is located.
   ****************************************************************************************
   */
  void assert_param2(int param0, int param1, const char * file, int line);
  
  /**
   ****************************************************************************************
   * @brief Print the assertion warning reason.
   *
   * @param param0 parameter value 0.
   * @param param1 parameter value 1.
   * @param file C string containing file where the assertion is located.
   * @param line Line number in the file where the assertion is located.
   ****************************************************************************************
   */
  void assert_warn(int param0, int param1, const char * file, int line);
  
  
  /**
   ****************************************************************************************
   * @brief Dump data value into FW.
   *
   * @param data start pointer of the data.
   * @param length data size to dump
   ****************************************************************************************
   */
  void dump_data(uint8_t* data, uint16_t length);
#endif //PLF_DEBUG

/*
 * ASSERTION CHECK
 ****************************************************************************************
 */
#if PLF_DEBUG
  /// Assertions showing a critical error that could require a full system reset
  #define ASSERT_ERR(cond)                              \
      do {                                              \
          if (!(cond)) {                                \
              assert_err(#cond, __MODULE__, __LINE__);  \
          }                                             \
      } while(0)
  
  /// Assertions showing a critical error that could require a full system reset
  #define ASSERT_INFO(cond, param0, param1)             \
      do {                                              \
          if (!(cond)) {                                \
              assert_param2((int)param0, (int)param1, __MODULE__, __LINE__);  \
          }                                             \
      } while(0)
  
  /// Assertions showing a non-critical problem that has to be fixed by the SW
  #define ASSERT_WARN(cond, param0, param1)             \
      do {                                              \
          if (!(cond)) {                                \
              assert_warn((int)param0, (int)param1, __MODULE__, __LINE__); \
          }                                             \
      } while(0)
  
  #define DUMP_DATA(data, length) \
      dump_data((uint8_t*)data, length)
  
  #else
  /// Assertions showing a critical error that could require a full system reset
  #define ASSERT_ERR(cond)
  
  /// Assertions showing a critical error that could require a full system reset
  #define ASSERT_INFO(cond, param0, param1)
  
  /// Assertions showing a non-critical problem that has to be fixed by the SW
  #define ASSERT_WARN(cond, param0, param1)
  
  /// DUMP data array present in the SW.
  #define DUMP_DATA(data, length)
#endif //PLF_DEBUG


// required to define GLOBAL_INT_** macros as inline assembly. This file is included after
// definition of ASSERT macros as they are used inside ll.h
#ifndef CRITICAL_SECT_START
  #define CRITICAL_SECT_START()    do{ uint32_t __irq_mask = __get_PRIMASK();  __disable_irq();
#endif
#ifndef CRITICAL_SECT_END 
  #define CRITICAL_SECT_END()      if(__irq_mask==0) {__enable_irq();} }while(0);
#endif
#ifndef GLOBAL_INT_START 
  #define GLOBAL_INT_START()      __enable_irq()
#endif
#ifndef GLOBAL_INT_STOP 
  #define GLOBAL_INT_STOP()       __disable_irq()
#endif
#ifndef GLOBAL_INT_DISABLE 
  #define GLOBAL_INT_DISABLE()    CRITICAL_SECT_START()
#endif
#ifndef GLOBAL_INT_RESTORE 
  #define GLOBAL_INT_RESTORE()    CRITICAL_SECT_END()
#endif

#endif // __BLE_STACK_ARCH_H__
